import Home from './modules/home';
import Base from './modules/base';
import pageJson from '@/pages.json';

const PerfectRouter = (pageJson: any): ClassDecorator => {
    function setRouter(routers: any) {
        for (let key in routers) {
            const currentRouter = pageJson.pages.find((item: any) => item.router == key);
            currentRouter && (routers[key] =  '/' + currentRouter.path);
        }
        return routers;
    }
    return (target: any) => {
        target.Home = setRouter(Home);
        target.Base = setRouter(Base);
    }
}

type BaseConfigType = {
    params?: { [props: string]: any };
    isEncode?: boolean
}

@PerfectRouter(pageJson)
export class Router {
    private static _TAB_BAR_PARAMS: { [props: string]: any } = {}; // 保存跳转tabBar页面参数

    public static get TAB_BAR_PARAMS() {
        if (Object.keys(this._TAB_BAR_PARAMS).length) {
            const params = Object.assign({}, this._TAB_BAR_PARAMS);
            this._TAB_BAR_PARAMS = {};
            return params;
        } else {
            return {}
        }
    }

    public static set TAB_BAR_PARAMS(e: { [props: string]: any }) {
        this._TAB_BAR_PARAMS = e;
    }

    public static Home = Home;

    public static Base = Base;

    /**
     * 格式化参数
     * @param params 参数 支持格式 [] | [{}] | boolean | {}
     * @param isEncode 是否加密
     */
    public static formatParams(params: { [props: string]: any } = {}, isEncode?: boolean) {

        const keys = Object.keys(params);

        if (!keys.length) return '';

        let new_params = '';

        keys.forEach((key: string) => {
            new_params += new_params ? '&' : '';
            if (Array.isArray(params[key])) {
                new_params += (key + '=' + params[key].map((item: any) => typeof item === 'object' ? JSON.stringify(item) : item).join('|'));
            } else switch (typeof params[key]) {
                case "object":
                    new_params += (key + '=' + JSON.stringify(params[key]));
                    break;
                default:
                    new_params += (key + '=' + params[key]);
            }
        });

        return '?' + (isEncode ? 'encode=' + Router.encodeParams(new_params) : new_params);
    }

    /**
     * 格式化结构
     * @param params
     */
    public static formatStructure(params: { [props: string]: any } = {}) {

        let decodeParams = Object.assign({}, params);

        if (decodeParams.hasOwnProperty('encode')) {
            Router.decodeParams(decodeParams.encode).split('&').forEach(item => {
                const res= item.split('=');
                decodeParams[res[0]] = res[1];
            });
            delete decodeParams.encode;
        }

        const keys = Object.keys(decodeParams);

        if (!keys.length) return {};

        let new_params: any = {};

        keys.forEach((key: string) => {
            if (decodeParams[key].includes('|')) {
                new_params[key] = decodeParams[key].split('|').map((item: any) => (item.includes("{") ? JSON.parse(item) : item));
            } else if (decodeParams[key].startsWith('{')) {
                new_params[key] = JSON.parse(decodeParams[key]);
            } else if (decodeParams[key] == 'true' || decodeParams[key] == 'false') {
                new_params[key] = (decodeParams[key] == 'true');
            } else {
                new_params[key] = decodeParams[key];
            }
        });

        return new_params;
    }

    /**
     * 封装navigate 保留当前页面跳转其他页面
     * @param config { params: { name: '' } 参数对象, isEncode: 是否加密 }
     */
    public static to(config:  UniApp.NavigateToOptions & BaseConfigType) {
        uni.navigateTo({
            url: config.url + Router.formatParams(config.params || {}, config.isEncode),
            events: config.events,
            success: config.success,
            fail: config.fail,
            complete: config.complete
        });
    }

    /**
     * 封装redirectTo 关闭当前页面跳转其他页面
     * @param config { params: { name: '' } 参数对象, isEncode: 是否加密 }
     */
    public static redirectTo(config:  UniApp.NavigateToOptions & BaseConfigType) {
        uni.redirectTo({
            url: config.url + Router.formatParams(config.params || {}, config.isEncode),
            success: config.success,
            fail: config.fail,
            complete: config.complete
        });
    }

    /**
     * 封装reLaunch 关闭所有页面，打开到应用内的某个页面。
     * @param config { params: { name: '' } 参数对象, isEncode: 是否加密 }
     */
    public static reLaunch(config:  UniApp.NavigateToOptions & BaseConfigType) {
        uni.reLaunch({
            url: config.url + Router.formatParams(config.params || {}, config.isEncode),
            success: config.success,
            fail: config.fail,
            complete: config.complete
        });
    }

    /**
     * 封装switchTab 跳转tabBar页面关闭其他非TabBar页面 可以携带参数tabBar 通过 Router.TAB_BAR_PARAMS 获取
     * @param config { params: { name: '' } 参数对象 }
     */
    public static switchTab(config:  UniApp.NavigateToOptions & BaseConfigType) {
        this.TAB_BAR_PARAMS = config.params || {};
        uni.switchTab({
            url: config.url,
            success: config.success,
            fail: config.fail,
            complete: config.complete
        });
    }

    public static decodeParams(params: string) {
        return decodeURIComponent(params);
    }

    public static encodeParams(params: string): string {
        return encodeURIComponent(params);
    }
}